home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
3DDEMO.ZIP
/
3D
/
SOURCE
/
FILE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-21
|
21KB
|
582 lines
#include "file.hpp"
// Copyright (c) 1996 by Kerrigan Burgess, all rights reserved.
FILESYSTEMCLASS::FILESYSTEMCLASS(void) // constructor.
{
}
FILESYSTEMCLASS::~FILESYSTEMCLASS(void) // destructor.
{
}
int ObjectId=0;
int FILESYSTEMCLASS::CreateDataBase(MESHCLASS *Mesh, char *filename, int Status)
{
char *type;
type=strrchr(filename,'.'); // look for filename extension.
type++; // move pointer by 1.
if (strncmp(type,"asc",3)==0)
LoadASC(Mesh,filename,Status);
else
if (strncmp(type,"gem",3)==0)
LoadGEM(Mesh,filename,Status);
else
if (strncmp(type,"geo",3)==0)
LoadGEO(Mesh,filename,Status);
else
{
Error("Unrecognized mesh format\n");
}
return (ObjectId);
}
void FILESYSTEMCLASS::LoadASC(MESHCLASS *Mesh, char *filename, int Status)
{
FILE *fptr;
char buffer[200], name[20];
char *token;
int tindex=0,vertices,faces;
float fraction;
double integral;
int TextureMapped;
fptr=fopen(filename,"r");
if (fptr==NULL)
Error("Couldn't find mesh\n");
while ( !feof(fptr) )
{
fgets(buffer,200,fptr);
token=strtok(buffer," \t");
if (!strcmp(token,"Named")) // Look for Named object:
{
TextureMapped = FALSE; // reset for this object.
token=strtok(NULL," \t"); // junk.
token=strtok(NULL," \t");
sscanf(token,"%s",name);
fgets(buffer,200,fptr);
token=strtok(buffer," \t");
while (strcmp(token,"Tri-mesh,")) // if not Tri-mesh get next line.
{ // see if now its Tri-mesh.
fgets(buffer,200,fptr);
token=strtok(buffer," \t");
}
token=strtok(NULL," \t"); // junk.
token=strtok(NULL," \t");
sscanf(token,"%d",&vertices);
token=strtok(NULL," \t"); // junk.
token=strtok(NULL," \t");
sscanf(token,"%d",&faces);
fgets(buffer,200,fptr); // junk.
token=strtok(buffer," \t");
while (strcmp(token,"Vertex")) // loop until we get Vertex list:
{
fgets(buffer,200,fptr);
token=strtok(buffer," \t");
}
int count;
OBJECTCLASS *Object = new OBJECTCLASS; // creates a new object and adds to list.
if (Object==NULL)
Error("not enough memory\n");
Object->numvertices=vertices;
Object->numpoly=faces;
Mesh->totalfaces+=faces; // update total faces. Used to allocate MeshList.
strcpy(Object->name,name);
Object->ObjectID = ++ObjectId;
int totalvertices;
totalvertices = 2*vertices; // because we want to allocate enough
// space to hold all vertices+avgnormals.
Object->LocalCoord = new POINT3D[totalvertices]; // allocate space for vertices.
if (Object->LocalCoord==NULL)
Error("not enough memory\n");
Object->CameraCoord = new POINT3D[totalvertices];
if (Object->CameraCoord==NULL)
Error("not enough memory\n");
// zero everything out.
memset(Object->LocalCoord, '\0', sizeof(POINT3D)*totalvertices);
memset(Object->CameraCoord, '\0', sizeof(POINT3D)*totalvertices);
for (count=0;count<vertices;count++)
{
fgets(buffer,200,fptr); // read in next line.
token=strtok(buffer," \t");
while (strcmp(token,"Vertex")) // if not Tri-mesh get next line.
{
fgets(buffer,200,fptr);
token=strtok(buffer," \t");
}
token=strtok(NULL," \t"); // junk.
token=strtok(NULL," \t");
if ( strlen(token) != 2 )
{
sscanf(&token[2],"%f",&(Object->LocalCoord[count].x));
}
else
{
token=strtok(NULL," \t");
sscanf(token,"%f",&(Object->LocalCoord[count].x));
}
token=strtok(NULL," \t");
if ( strlen(token) != 2 )
{
sscanf(&token[2],"%f",&(Object->LocalCoord[count].y));
}
else
{
token=strtok(NULL," \t");
sscanf(token,"%f",&(Object->LocalCoord[count].y));
}
token=strtok(NULL," \t");
if ( strlen(token) != 2 )
{
sscanf(&token[2],"%f",&(Object->LocalCoord[count].z));
}
else
{
token=strtok(NULL," \t");
sscanf(token,"%f",&(Object->LocalCoord[count].z));
}
token=strtok(NULL," \t");
if (strncmp(token,"U:",2)==0)
{
TextureMapped=TRUE;
if ( strlen(token) != 2 )
{
sscanf(&token[2],"%f",&fraction);
if (fraction<0)
fraction = -fraction;
if (fraction>1)
fraction=modf((double)fraction,&integral);
Object->CameraCoord[count].u = (int)255*fraction;
}
else
{
token=strtok(NULL," \t");
sscanf(token,"%f",&fraction);
if (fraction<0)
fraction = -fraction;
if (fraction>1)
fraction=modf((double)fraction,&integral);
Object->CameraCoord[count].u = (int)255*fraction;
}
token=strtok(NULL," \t");
if ( strlen(token) != 2 )
{
sscanf(&token[2],"%f",&fraction);
if (fraction<0)
fraction = -fraction;
if (fraction>1)
fraction=modf((double)fraction,&integral);
Object->CameraCoord[count].v = (int)255*fraction;
}
else
{
token=strtok(NULL," \t");
sscanf(token,"%f",&fraction);
if (fraction<0)
fraction = -fraction;
if (fraction>1)
fraction=modf((double)fraction,&integral);
Object->CameraCoord[count].v = (int)255*fraction;
}
}
} // end for loop (vertices).
Object->FindCenter(); // translate vertices to center of rotation.
Object->ComputeRadius(); // used for object level culling, also scales object.
Object->Polygon = new POLYGONCLASS[faces]; // allocate faces.
if (Object->Polygon==NULL)
Error("Not enough memory\n");
memset(Object->Polygon, '\0', sizeof(POLYGONCLASS)*faces); // zero out everything.
POLYGONCLASS *Polygon; // alias for This face.
int vertex0,vertex1,vertex2;
struct tempstruct *polyinfo; // used for precomputing avgnormals.
polyinfo = new struct tempstruct[faces];
if (polyinfo==NULL)
Error("not enough memory\n");
fgets(buffer,200,fptr); // junk.
token=strtok(buffer," \t");
while (strcmp(token,"Face")) // loop until we get Face list:
{
fgets(buffer,200,fptr);
token=strtok(buffer," \t");
}
int pindex;
for (pindex=0;pindex<faces;pindex++)
{
fgets(buffer,200,fptr); // read in next line.
token=strtok(buffer," \t");
while (strcmp(token,"Face")) // if not Face get next line.
{
fgets(buffer,200,fptr);
token=strtok(buffer," \t");
}
Polygon=&(Object->Polygon[pindex]);
token=strtok(NULL," \t"); // junk.
// point directly to address of camera coords.
token=strtok(NULL," \t");
sscanf(&token[2],"%d",&vertex0);
Polygon->Vertex[0]=&(Object->CameraCoord[vertex0]);
token=strtok(NULL," \t");
sscanf(&token[2],"%d",&vertex1);
Polygon->Vertex[1]=&(Object->CameraCoord[vertex1]);
token=strtok(NULL," \t");
sscanf(&token[2],"%d",&vertex2);
Polygon->Vertex[2]=&(Object->CameraCoord[vertex2]);
Polygon->color = 252*(SHADES+1); // make it shades of white.
Polygon->shadowcolor = 0; // make it black.
if (TextureMapped)
{
Polygon->u0 = (Object->CameraCoord[vertex0]).u;
Polygon->v0 = (Object->CameraCoord[vertex0]).v;
Polygon->u1 = (Object->CameraCoord[vertex1]).u;
Polygon->v1 = (Object->CameraCoord[vertex1]).v;
Polygon->u2 = (Object->CameraCoord[vertex2]).u;
Polygon->v2 = (Object->CameraCoord[vertex2]).v;
}
else // since it's not T-mapped, put in own coords.
{
Polygon->u0 = 3;
Polygon->v0 = 3;
Polygon->u1 = 127;
Polygon->v1 = 3;
Polygon->u2 = 127;
Polygon->v2 = 127;
}
polyinfo[pindex].p0 = vertex0; // save vertex indices for computing avgnormals.
polyinfo[pindex].p1 = vertex1;
polyinfo[pindex].p2 = vertex2;
Object->ComputeNormalength(vertex0,vertex1,vertex2,Polygon);
} // end while (faces).
Object->PreComputeAvgNormal(polyinfo);
Object->numvertices=totalvertices; // adjust vertices by 2x.
Mesh->Push(Object,Status); // Add Object to linked list. Parent or Child?
delete polyinfo; // delete temporary structure for precomputing avgnormals.
} // end if (Named).
} // end while (!eof).
}
void FILESYSTEMCLASS::LoadGEM(MESHCLASS *Mesh, char *filename, int Status)
{
FILE *fptr;
char buffer[200];
char *token;
int junk,count,vertices,faces,totalfaces=0;
int vertexcount;
fptr=fopen(filename,"r");
if (fptr==NULL)
Error("Couldn't find mesh\n");
if ( !feof(fptr) )
{
fscanf(fptr,"%d %d %d\n",&vertices,&faces,&junk);
OBJECTCLASS *Object = new OBJECTCLASS; // creates a new object and adds to list
if (Object==NULL)
Error("not enough memory\n");
Object->numvertices=vertices;
Object->ObjectID = ++ObjectId;
int totalvertices;
totalvertices = 2*vertices; // because we want to allocate enough
// space to hold all vertices+avgnormals.
Object->LocalCoord = new POINT3D[totalvertices]; // allocate space for vertices.
if (Object->LocalCoord==NULL)
Error("not enough memory\n");
Object->CameraCoord = new POINT3D[totalvertices];
if (Object->CameraCoord==NULL)
Error("not enough memory\n");
// zero everything out.
memset(Object->LocalCoord, '\0', sizeof(POINT3D)*totalvertices);
memset(Object->CameraCoord, '\0', sizeof(POINT3D)*totalvertices);
for (count=0;count<vertices;count++) // read in vertices.
{
fscanf( fptr,"%f %f %f\n",&(Object->LocalCoord[count].x),
&(Object->LocalCoord[count].y),
&(Object->LocalCoord[count].z) );
}
Object->FindCenter(); // translate vertices so rotation is around the center.
Object->ComputeRadius(); // used for object level culling, also scales object.
long offset,lines=0; // save file pointer offset.
offset=ftell(fptr); // find out where we are in file.
for (count=0;count<faces;count++) // get actual count of faces. (some polys may have more than 3 vertices.)
{
fgets(buffer,200,fptr);
token=strtok(buffer," \t");
sscanf(token,"%d",&vertexcount);
totalfaces=totalfaces+1+(vertexcount-3); // to split polygons with vertices > 3 into smaller polys.
lines++;
}
fseek(fptr,offset,SEEK_SET); // return to original position.
Object->numpoly=totalfaces;
Mesh->totalfaces+=totalfaces; // update total faces. Used to allocate MeshList.
Object->Polygon = new POLYGONCLASS[totalfaces]; // allocate faces.
if (Object->Polygon==NULL)
Error("not enough memory\n");
memset(Object->Polygon, '\0', sizeof(POLYGONCLASS)*totalfaces); // zero out everything.
POLYGONCLASS *Polygon; // alias for This face.
struct tempstruct *polyinfo; // used for precomputing avgnormals.
polyinfo = new struct tempstruct[totalfaces];
if (polyinfo==NULL)
Error("not enough memory\n");
int VertexId[20]; // should be enough.
int pindex;
pindex=0;
while (lines-- > 0)
{
fgets(buffer,200,fptr);
token=strtok(buffer," \t");
sscanf(token,"%d",&vertexcount);
for (count=vertexcount;count>0;count--) // put in counterclockwise order.
{
token=strtok(NULL," \t");
sscanf(token,"%d",&VertexId[count-1]);
VertexId[count-1]-=1; // index vertices for polys start at 0 not 1.
}
vertexcount=1+(vertexcount-3); // this polygon has to be broken into vertexcount polys.
for (count=0;count<vertexcount;count++)
{
Polygon=&(Object->Polygon[pindex]); // alias a pointer.
Polygon->Vertex[0]=&(Object->CameraCoord[ VertexId[0] ]); // point directly to cameracoords
Polygon->Vertex[1]=&(Object->CameraCoord[ VertexId[count+1] ]);
Polygon->Vertex[2]=&(Object->CameraCoord[ VertexId[count+2] ]);
Polygon->color = 252*(SHADES+1); // make it shades of white.
Polygon->shadowcolor = 0; // make it black.
Polygon->u0 = 3; // supply own u,v coords.
Polygon->v0 = 3;
Polygon->u1 = 127;
Polygon->v1 = 3;
Polygon->u2 = 127;
Polygon->v2 = 127;
polyinfo[pindex].p0 = VertexId[0]; // save vertex indices for computing avgnormals.
polyinfo[pindex].p1 = VertexId[count+1];
polyinfo[pindex].p2 = VertexId[count+2];
Object->ComputeNormalength(VertexId[0], VertexId[count+1], VertexId[count+2], Polygon);
pindex++; // get next polygon.
}
} // end while (faces).
Object->PreComputeAvgNormal(polyinfo);
Object->numvertices=totalvertices; // adjust vertices by 2x.
Mesh->Push(Object,Status); // Add Object to linked list. Parent or Child?
delete polyinfo; // delete temporary structure for precomputing avgnormals.
} // end if (!eof).
}
void FILESYSTEMCLASS::LoadGEO(MESHCLASS *Mesh, char *filename, int Status)
{
FILE *fptr;
char buffer[200];
char *token;
int count,vertices,totalfaces=0;
int vertexcount;
fptr=fopen(filename,"r");
if (fptr==NULL)
Error("Couldn't find mesh\n");
if ( !feof(fptr) )
{
fgets(buffer,200,fptr); // read header.
fscanf(fptr,"%d\n",&vertices); // num of vertices.
OBJECTCLASS *Object = new OBJECTCLASS; // creates a new object and adds to list
if (Object==NULL)
Error("not enough memory\n");
Object->numvertices=vertices;
Object->ObjectID = ++ObjectId;
int totalvertices;
totalvertices = 2*vertices; // because we want to allocate enough
// space to hold all vertices+avgnormals.
Object->LocalCoord = new POINT3D[totalvertices]; // allocate space for vertices.
if (Object->LocalCoord==NULL)
Error("not enough memory\n");
Object->CameraCoord = new POINT3D[totalvertices];
if (Object->CameraCoord==NULL)
Error("not enough memory\n");
// zero everything out.
memset(Object->LocalCoord, '\0', sizeof(POINT3D)*totalvertices);
memset(Object->CameraCoord, '\0', sizeof(POINT3D)*totalvertices);
for (count=0;count<vertices;count++) // read in vertices.
{
fscanf( fptr,"%f %f %f\n",&(Object->LocalCoord[count].x),
&(Object->LocalCoord[count].y),
&(Object->LocalCoord[count].z) );
}
Object->FindCenter(); // translate vertices so rotation is around the center.
Object->ComputeRadius(); // used for object level culling, also scales object.
long offset,lines=0; // save file pointer offset.
offset=ftell(fptr); // find out where we are in file.
for (;;)
{
if (fgets(buffer,200,fptr) == NULL)
break; // reached EOF.
else
{
token=strtok(buffer," \t");
sscanf(token,"%d",&vertexcount);
if (vertexcount>2) // only add to total faces if vertices are greater than 2.
totalfaces=totalfaces+1+(vertexcount-3); // to split polygons with vertices > 3 into smaller polys.
lines++;
}
}
fseek(fptr,offset,SEEK_SET); // return to original position.
Object->numpoly=totalfaces;
Mesh->totalfaces+=totalfaces; // update total faces. Used to allocate MeshList.
Object->Polygon = new POLYGONCLASS[totalfaces]; // allocate faces.
if (Object->Polygon==NULL)
Error("not enough memory\n");
memset(Object->Polygon, '\0', sizeof(POLYGONCLASS)*totalfaces); // zero out everything.
POLYGONCLASS *Polygon; // alias for This face.
struct tempstruct *polyinfo; // used for precomputing avgnormals.
polyinfo = new struct tempstruct[totalfaces];
if (polyinfo==NULL)
Error("not enough memory\n");
int VertexId[20]; // should be enough.
int pindex;
pindex=0;
while (lines-- > 0)
{
fgets(buffer,200,fptr); // read in next line.
token=strtok(buffer," \t");
sscanf(token,"%d",&vertexcount);
if (vertexcount<3) // if vertices don't makeup a complete poly, continue.
continue;
for (count=0;count<vertexcount;count++)
{
token=strtok(NULL," \t");
sscanf(token,"%d",&VertexId[count]);
}
vertexcount=1+(vertexcount-3); // this polygon has to be broken into vertexcount polys.
for (count=0;count<vertexcount;count++)
{
Polygon=&(Object->Polygon[pindex]); // alias a pointer.
Polygon->Vertex[0]=&(Object->CameraCoord[ VertexId[0] ]); // point directly to cameracoords
Polygon->Vertex[1]=&(Object->CameraCoord[ VertexId[count+1] ]);
Polygon->Vertex[2]=&(Object->CameraCoord[ VertexId[count+2] ]);
Polygon->color = 252*(SHADES+1); // make it shades of white.
Polygon->shadowcolor = 0; // make it black.
Polygon->u0 = 3; // supply own u,v coords.
Polygon->v0 = 3;
Polygon->u1 = 127;
Polygon->v1 = 3;
Polygon->u2 = 127;
Polygon->v2 = 127;
polyinfo[pindex].p0 = VertexId[0]; // save vertex indices for computing avgnormals.
polyinfo[pindex].p1 = VertexId[count+1];
polyinfo[pindex].p2 = VertexId[count+2];
Object->ComputeNormalength(VertexId[0], VertexId[count+1], VertexId[count+2], Polygon);
pindex++; // get next polygon.
}
} // end while (faces).
Object->PreComputeAvgNormal(polyinfo);
Object->numvertices=totalvertices; // adjust vertices by 2x.
Mesh->Push(Object,Status); // Add Object to linked list. Parent or Child?
delete polyinfo; // delete temporary structure for precomputing avgnormals.
} // end if (!eof).
}